<template>
  <div class="container-lg main" id="activitydata">
    <div
      class="row m-0"
      :style="{ backgroundImage: `url(${imgs[jianchatime(activity).text]})` }"
    >
      <div class="col co-1">
        <h2
          :style="{
            fontWeight: 700,
          }"
          class="title"
        >
          {{ activity.name }}
        </h2>
        <div class="time">结束时间：{{ TimeYH(activity.activityendtime) }}</div>
      </div>
      <div class="col-2 text-right">
        <h2
          :style="{
            fontWeight: 700,
          }"
          class="title"
        ></h2>
        <el-button @click="download2">下载成绩</el-button>
      </div>
    </div>
    <div class="row m-0">
      <div class="col co-1">
        <ul class="nav nav-tabs">
          <li
            :class="index === 2 ? 'nav-item-active' : ''"
            @click="setindex(2)"
            class="nav-item"
          >
            <span class="nav-link" href="#">得分排行</span>
          </li>
          <li
            :class="index === 3 ? 'nav-item-active' : ''"
            v-if="!activity.isduplicate"
            @click="setindex(3)"
            class="nav-item"
          >
            <span class="nav-link" href="#">比赛代码查重</span>
          </li>
        </ul>
      </div>
    </div>
    <div
      class="row"
      :style="{
        marginLeft: '48px',
        marginRight: '48px',
      }"
    >
      <div
        class="col"
        :style="{
          backgroundColor: '#fff',
          minHeight: '65vh',
          paddingLeft: '24px',
          paddingRight: '24px',
          paddingBottom: '24px',
        }"
      >
        <div :style="{ color: '#434343', fontSize: '12px', marginTop: '12px' }">
          注：{{
            index === 3
              ? "1）系统采用智能化查重方式，不止比较代码文本，还会根据代码语义进行智能判断；2）只对有获得得分的代码进行查重，查重结果相似度极高的代码会在这里展示。"
              : "若比赛过程中，该排行题号为非真实题号。"
          }}
        </div>

        <table
          class="table"
          v-show="index === 3"
          :style="{ marginBottom: '0px', marginTop: '24px' }"
        >
          <tr>
            <th
              v-for="(v, key) in bodykey.index.filter((e) =>
                e.index.includes(index)
              )"
              :key="`${key}_index`"
              :style="v.style"
              :width="v.width"
              scope="col"
            >
              {{ v.name }}
            </th>
          </tr>
        </table>
        <el-collapse
          accordion
          v-show="index === 3"
          v-model="index_1"
          :style="{ width: '100%' }"
        >
          <el-collapse-item
            class="el-collapse-item"
            v-for="(t, i) in body2"
            :name="i"
          >
            <template #title>
              <table class="table" :style="{ marginBottom: 0 }">
                <tbody>
                  <tr>
                    <th width="200" :style="{ borderBottomWidth: '0' }">
                      {{ t?.user?.name }}
                    </th>
                    <td
                      width="100"
                      v-show="[0, 1, 2, 3].includes(index)"
                      :style="{ borderBottomWidth: '0' }"
                    >
                      {{ t?.df }}
                    </td>
                    <td scope="col" :style="{ borderBottomWidth: '0' }">
                      {{ t?.teams?.join(",") }}
                    </td>
                    <td
                      width="200"
                      v-show="[0, 1, 2].includes(index)"
                      :style="{ borderBottomWidth: '0' }"
                    >
                      {{ TimeYH(t?.createdAt) }}
                    </td>
                  </tr>
                </tbody>
              </table>
            </template>
            <div>
              <table class="table mb-0" :style="{ marginBottom: 0 }">
                <tbody>
                  <tr v-for="(v, e) in t?.list" :key="i + '_' + e">
                    <th width="100" :style="{ borderBottomWidth: '0px' }">
                      第{{ !isNaN(v.index) ? v.index + 1 : e + 1 }}题
                    </th>
                    <td
                      width="100"
                      v-show="[0, 1, 2].includes(index)"
                      :style="{ borderBottomWidth: '0px' }"
                    >
                      {{ v.df }}
                    </td>
                    <td
                      width="100"
                      v-show="[0, 1, 2].includes(index)"
                      :style="{ borderBottomWidth: '0px' }"
                    >
                      <div class="div1" :class="v.result">
                        {{ v.resultdata }}
                      </div>
                    </td>
                    <td
                      v-show="[0, 1, 2].includes(index)"
                      :style="{ borderBottomWidth: '0px' }"
                    >
                      <div v-if="Array.isArray(v.resultdataarr)">
                        <span
                          v-for="(m, n) in v.resultdataarr"
                          class="span1"
                          :key="i + '_' + e + '_' + n"
                          :class="ALLTYPE[m][1]"
                          >{{ m }}</span
                        >
                      </div>
                    </td>

                    <td
                      v-if="index === 3"
                      :style="{ borderBottomWidth: '0px' }"
                    >
                      <span
                        v-for="(code, key) in v.code"
                        :key="`code_${key}`"
                        class="a-down"
                        target="_blank"
                        @click.stop="
                          dowmload1(
                            {
                              userid: code.ID,
                              questionid: v.questionid,
                              name: code?.name,
                            },
                            {
                              userid: t.user?.ID,
                              questionid: v.questionid,
                              name: t.user?.name,
                            }
                          )
                        "
                        >{{ code.name }}</span
                      >
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </el-collapse-item>
        </el-collapse>

        <el-table v-show="index != 3" :data="body3" style="width: 100%">
          <template v-slot:empty>
            <el-empty
              image="https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/image/ojSass-empty.png"
            />
          </template>
          <el-table-column
            type="index"
            width="80"
            label="排名"
            fixed
            sortable
          />
          <el-table-column prop="name" label="用户名称" fixed width="160">
            <template #default="scope">
              {{ scope.row.name }}
              {{
                scope.row.xingming
                  ? scope.row.name === scope.row.xingming
                    ? ""
                    : `(${scope.row.xingming})`
                  : ""
              }}
            </template>
          </el-table-column>
          <el-table-column
            prop="updatedAt"
            label="提交时间"
            width="160"
            sortable
          >
            <template #default="scope">
              {{ TimeYH(scope.row.createdAt) }}
            </template>
          </el-table-column>

          <el-table-column prop="df" label="总分" width="100" sortable>
            <template #default="scope">
              <div class="text-center" :class="className2(scope.row)">
                {{ scope.row.df }}
              </div>
            </template>
          </el-table-column>
          <el-table-column
            v-for="(item, key) in matchquestion"
            :prop="String(key)"
            :label="`第${key + 1}题`"
            class-name="el-table-column text-center"
            sortable
          >
            <template #default="scope">
              <el-tooltip
                class="box-item"
                effect="light"
                content="查看代码"
                placement="top"
              >
                <div
                  :class="className(scope.row, item, key)"
                  class="cu text-center"
                  @click="getcode(scope.row, item)"
                >
                  {{ scope.row[String(key)] }}
                </div>
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
        <div v-show="index === 3 && img" :style="{ textAlign: 'center' }">
          <div class="alert">
            <svg class="icon" aria-hidden="true" v-show="img === 2">
              <use xlink:href="#icon-Clock_filled"></use>
            </svg>
            <svg class="icon" aria-hidden="true" v-show="img === 1">
              <use xlink:href="#icon-Shape"></use>
            </svg>
            &nbsp; &nbsp;
            {{
              img === 2
                ? "代码查重将会在比赛结束后约2-3h内完成"
                : "本次比赛查重完成没有相似代码"
            }}
          </div>
          <img
            :src="
              img === 1
                ? 'https://cdn.hterobot.com/JOY/oj_1_1/bisaidaimachachong_chachongwancheng.png'
                : 'https://cdn.hterobot.com/JOY/oj_1_1/bisaidaimachachong_zhengzaichachong.png'
            "
            width="480"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  asyncgetactivity,
  asyncgetsim,
  asyncgetusermatchcode,
  asyncselectmatchquestion,
  asyncselectmatchranking,
  asyncteamselectmatchuserquestion,
  ISIM,
} from "../../../api";
import { Storekey } from "../../../interface";
import { jianchatime, ALLTYPE } from "@/util/jianchatime";
import { TimeYH } from "../../../util/time";
import Studycodemodel from "../../../mysql_interface/studycodemodel";
import { assign } from "underscore";
import { encode, encodeURI } from "js-base64";
import {
  computed,
  onBeforeUnmount,
  onMounted,
  reactive,
  ref,
  watch,
} from "vue";
import { useStore } from "vuex";
import { ElMessage } from "element-plus";
import { getExceltodownload } from "../../../util/excel";

const bodykey = {
  index: [
    {
      index: [0, 1, 2, 3],
      name: "姓名",
      width: "200",
      style: { borderColor: "var(--color-43)", padding: "20px 12px" },
    },
    {
      index: [0, 1, 2],
      name: "当前得分",
      width: "100",
      style: { borderColor: "var(--color-43)", padding: "20px 12px" },
    },
    {
      index: [3],
      name: "总得分",
      width: "100",
      style: { borderColor: "var(--color-43)", padding: "20px 12px" },
    },
    {
      index: [0, 1, 2],
      name: "团队名称",
      style: { borderColor: "var(--color-43)", padding: "20px 12px" },
    },
    {
      index: [0, 1, 2],
      name: "提交时间",
      width: "200",
      style: { borderColor: "var(--color-43)", padding: "20px 12px" },
    },
    {
      index: [3],
      name: "编程题代码高度相似数",
      style: { borderColor: "var(--color-43)", padding: "20px 12px" },
    },
  ],
  title: [
    { index: [0, 1, 2, 3], name: "题号", width: "100" },
    { index: [0, 1, 2], name: "得分", width: "100" },
    { index: [0, 1, 2], name: "状态", width: "100", className: "text-center" },
    { index: [0, 1, 2], name: "测试点信息" },
    { index: [3], name: "高度相似(相似度>85%)" },
    { index: [3], name: "下载源码", width: "100", className: "text-center" },
  ],
};

const index_1 = ref();

const limit = ref(1000);
const offset = ref(0);

const p = defineProps<{ ID: number }>();
const store = useStore(Storekey);
const team = computed(() => {
  return store.state.team?.rows || [];
});
const index = ref(2);

const users = ref<Studycodemodel.Iuser[]>([]);

const activity = reactive<Studycodemodel.Iactivity>({});
const body = ref<Studycodemodel.Imatchranking[]>([]);

const body3 = computed(() => {
  const data = matchquestion.value.map((e) => e.name);
  return users.value
    .map((f) => {
      let k: Record<string | number, string | number | any[]> = {};
      const { ID } = f;
      const matchranking = body.value.find((e) => e.userid === ID);
      const _data = JSON.parse(matchranking?.data || "") as any[];
      for (const v in data) {
        const d = _data.find((z) => z[2] === data[v]);
        const f = d ? d[1] : 0;
        k[String(v)] = f ? f : 0;
      }
      k.resultdata =
        _data.map((e) => e[3]).filter((e) => e === "AC").length === _data.length
          ? "AC"
          : "UN";
      return {
        ...k,
        ...f,
        ...matchranking,
      };
    })
    .sort((a, b) => Number(b.df) - Number(a.df));
});

const body2 = computed(() => {
  const { users, data } = sim.value;
  return users
    .sort((a, b) => {
      const adf = body.value.find((z) => z.userid == a.ID);
      const bdf = body.value.find((z) => z.userid == b.ID);
      return Number(bdf?.df) - Number(adf?.df);
    })
    .map((e) => {
      const { ID } = e;
      const adf = body.value.find((z) => z.userid == ID);
      const t = data[String(ID)];
      if (t) {
        const code = matchquestion.value
          .filter((e) => {
            return Object.keys(t).includes(String(e.ID));
          })
          .map((z) => {
            const e = t[String(z.ID)] || [];
            const code = e.map((z) => {
              const [userid, fen] = z;
              const user = users.find((t) => t.ID === Number(userid));
              return assign({}, user, {
                name: `${user?.name} (相似度 ${fen}%)`,
              });
            });
            return {
              index: z.paixu,
              questionid: z.ID,
              code,
            };
          });
        return {
          df: adf?.df,
          user: e,
          list: code,
          teams: [`${code.length}题`],
        };
      }
    });
});

async function start() {
  if (p.ID) {
    const data = await asyncgetactivity({ ID: p.ID });
    Object.assign(activity, data);
  }
}

const sim = ref<ISIM>({ users: [], data: {} });

const matchquestion = ref<Studycodemodel.Imatchquestion[]>([]);

async function selectmatchquestion() {
  const [data] = await asyncselectmatchquestion({ activityid: p.ID });
  matchquestion.value = data.matchquestion || [];
}

const img = ref(1);

async function getsim() {
  asyncgetsim({ activityid: p.ID })
    .then((e) => {
      sim.value = e;
      if (Object.keys(e.data).length) {
        img.value = 0;
      }
    })
    .catch((e) => {
      img.value = 2;
      console.log(e);
    });
}

async function getbody() {
  const { user, matchranking } = await asyncselectmatchranking({
    activityid: p.ID,
    _offset: offset.value,
    _limit: limit.value,
    _order: "df",
    _sortable: "DESC",
  });
  users.value = user;
  if (activity.isranking) {
    body.value = matchranking;
  }
}

onMounted(async () => {
  // 进入房间
  await start();
  store.state.socket.emit("activity", { activityid: p.ID, com: true });
  store.state.socket.on("activity", () => {
    if (activity.isranking) {
      getbody();
    }
  });
  getsim();
  selectmatchquestion();
});

function className(
  params: Studycodemodel.Imatchranking,
  matchquestion: Studycodemodel.Imatchquestion,
  index: number
) {
  const { data } = params;
  const _data = JSON.parse(data || "[]") as any[];
  const n = _data[index];
  const c = n[1] / Number(matchquestion.score);
  if (c >= 0.7) {
    return "Accepted";
  } else if (c >= 0.3) {
    return "Unaccepted";
  } else {
    return "CompileError";
  }
}

function className2(params: Studycodemodel.Imatchranking) {
  const { df } = params;
  const c =
    Number(df) /
    Number(
      matchquestion.value
        .map((a) => Number(a.score))
        .reduce((c, d) => Number(c) + Number(d)),
      0
    );
  if (c >= 0.7) {
    return "Accepted";
  } else if (c >= 0.3) {
    return "Unaccepted";
  } else {
    return "CompileError";
  }
}

function setindex(i: number) {
  index.value = i;
}

watch(
  () => index.value,
  () => {
    index_1.value = "";
  }
);

onBeforeUnmount(() => {
  store.state.socket.emit("activity", { activityid: p.ID, com: false });
});

const imgs: Record<string, string> = {
  即将开赛:
    "https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/JOY/oj_1_1/jo_1_1_homepage/baiomingzhuangtai_weikaishi.svg",
  立即报名:
    "https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/JOY/oj_1_1/jo_1_1_homepage/baiomingzhuangtai_baomingzhong.svg",
  进入比赛:
    "https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/JOY/oj_1_1/jo_1_1_homepage/baiomingzhuangtai_bisaizhong.svg",
  赛事结束:
    "https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/JOY/oj_1_1/jo_1_1_homepage/baiomingzhuangtai_bisaijieshu.svg",
};

async function dowmload1(
  body: { userid: number; questionid: number; name: string },
  body2?: { userid: number; questionid: number; name: string }
) {
  const [data] = await asyncgetusermatchcode({
    userid: body.userid,
    questionid: body.questionid,
    activityid: p.ID,
  });
  let data2 = ["", ".cpp"];
  const d = data[0].split(".")[1];
  let language = "cpp";
  if (d === "py") {
    language = "python";
  }

  if (body2) {
    const [_data2] = await asyncgetusermatchcode({
      userid: body2.userid,
      questionid: body2.questionid,
      activityid: p.ID,
    });
    data2 = _data2;
    window.open(
      `https://cdn.hterobot.com/diffeditor/index.html?code1=${encode(
        data[1],
        true
      )}&code2=${encode(data2[1], true)}&language=${language}&name1=${encode(
        body.name,
        true
      )}&name2=${encodeURI(body2.name)}`
    );
  } else {
    window.open(
      `https://cdn.hterobot.com/diffeditor/index.html?code1=${
        (encode(data[1]), true)
      }&language=${language}&name1=${encode(body.name)}`
    );
  }
}

async function download2() {
  const act: (string | number | undefined)[][] = [
    ["#", "用户名称", "提交时间", "总分"],
  ];

  const _act = body3.value.map((v, k) => {
    return [
      k + 1,
      `${v.name}${
        v.xingming ? (v.name === v.xingming ? "" : `(${v.xingming})`) : ""
      }`,
      TimeYH(v.createdAt),
      v.df,
    ];
  });
  getExceltodownload(act.concat(_act), `比赛成绩表`);
}

async function getcode(params: any, index: Studycodemodel.Imatchquestion) {
  const { userid, name } = params;
  const questionid = index.ID;
  const activityid = p.ID;
  const teamid = activity.teamid || team.value[0]?.ID;
  if (index.type === "代码") {
    try {
      const { rows } = await asyncteamselectmatchuserquestion({
        userid,
        questionid,
        activityid,
        teamid,
      });
      if (rows.length) {
        const { context, language } = rows[0];
        window.open(
          `https://cdn.hterobot.com/diffeditor/index.html?code1=${encode(
            String(context),
            true
          )}&language=${language}&name1=${encode(
            name + " " + index.name,
            true
          )}`
        );
      } else {
        ElMessage.error("没有找到此题");
      }
    } catch (e) {
      ElMessage.error(e as any);
    }
  } else {
    ElMessage.error("此题不是代码题");
  }
}
</script>

<style scoped>
.m-0 {
  background-position-x: right;
  background-position-y: top;
  background-repeat: no-repeat;
}

.co-1 {
  padding-left: 48px;
  padding-right: 48px;
  background-position-x: right;
  background-position-y: top;
  background-repeat: no-repeat;
}

.title {
  height: 48px;
  color: #fff;
  font-size: 36px;
  line-height: 48px;
  margin-top: 48px;
}

.main {
  background-color: #454545;
  margin-top: 24px;
  border-radius: 2px;
  background-image: url(https://cdn.hterobot.com/JOY/oj_1_1/HGKJ_OJ_1.0_bisaipaiming_%20BG.png);
  background-position-x: center;
  background-repeat: no-repeat;
  background-size: contain;
  padding-bottom: 35px;
}

.time {
  background: #1f1f1f;
  box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.18);
  border-radius: 36px;
  width: 261px;
  height: 30px;
  font-size: 14px;
  line-height: 30px;
  color: #ffffff;
  padding-left: 24px;
  margin-top: 12px;
  margin-bottom: 12px;
}

.nav-item {
  margin-right: 10px;
  /* border-left: 1px solid #dcdfe6;
  border-right: 1px solid #dcdfe6; */
  border-top: 1px solid #dcdfe6;
  padding-top: 5px;
  font-size: 18px;
  border-top-left-radius: 0.25rem;
  border-top-right-radius: 0.25rem;
  line-height: 34px;
  background-color: #ffffff;
  width: 180px;
  text-align: center;
  border-bottom: 1px solid #dee2e6;
}

.nav-tabs .nav-item:hover {
  border-top: 6px solid var(--color-cheng);
  padding-top: 0px;
  border-color: var(--color-cheng);
  border-bottom-color: #fff;

  border-bottom-width: 1;
}

.nav-link {
  color: #000000;
}

.nav-tabs .nav-item-active {
  border-top: 6px solid var(--color-cheng);
  padding-top: 0px;
  border-color: var(--color-cheng);
  border-bottom-color: #fff;
  border-bottom-width: 1;
}

.nav-link {
  cursor: pointer;
  font-size: 18px;
  line-height: 28px;
  border: none !important;
}

.span1 {
  border-radius: 50%;
  display: inline-block;
  width: 25px;
  height: 25px;
  text-align: center;
  line-height: 26px;
  margin-right: 4px;
  font-size: 12px;
}

.cu:hover {
  text-decoration: underline;
}

.div1 {
  height: 24px;
  padding-left: 12px;
  padding-right: 12px;
  line-height: 24px;
  border-radius: 4px;
  text-align: center;
}

#activitydata .RuntimeError {
  background-color: blueviolet;
  color: #fff;
}

#activitydata .RuntimeError {
  background-color: blueviolet;
  color: #fff;
}

.WrongAnswer {
  background-color: #f5ac50;
  color: #ffffff;
}

.nav-tabs {
  border-width: 0;
}

.a-down {
  color: var(--cloor-43);
  padding-left: 10px;
  padding-right: 10px;
  text-decoration: underline;
  cursor: pointer;
}

.a-down:hover {
  color: var(--color-cheng);
}

.a-down:active {
  color: var(--color-cheng);
}

.el-collapse-item {
  margin-bottom: 24px;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
}
</style>
<style>
#activitydata .el-collapse {
  --el-collapse-border-color: none;
  --el-collapse-header-height: 48px;
  --el-collapse-header-text-color: var(--colo-43);

  --el-collapse-header-bg-color: #fafafa;
  --el-collapse-content-bg-color: #fff;
  --el-collapse-content-font-color: none;
  border-width: 0;
}

#activitydata .el-collapse-item__header:hover {
  --el-collapse-header-bg-color: #f5f5f5;
}

#activitydata .el-collapse-item__header.is-active {
  --el-collapse-header-bg-color: var(--color-43);
  --el-collapse-header-text-color: #f5f5f5;
}

#activitydata .el-collapse-item__header.is-active .table {
  color: var(--el-collapse-header-text-color);
}

#activitydata .el-collapse-item__header {
  border-radius: 2px;
  overflow: hidden;
}

#activitydata .el-collapse-item__content {
  padding: 0.5rem;
}

#activitydata .el-pager li {
  margin: 0;
}

#activitydata .el-table-column .cell {
  min-width: 120px;
}

.alert {
  flex-direction: row;
  justify-content: center;
  align-items: center;
  padding: 12px;
  gap: 12px;

  width: 480px;
  height: 52px;
  background: #f5f5f5;
  /* Layer_line */

  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 4px;
  margin: 24px auto;
  color: #000;
  font-size: 16px;
}
</style>
